//秒表对象
(function(factory){
    "use strict";
    if (typeof require === "function" && typeof module === "object" && typeof module.exports === "object"){
        module.exports = factory();
    } else {
        window['Conveyer'] = factory();
    }
})(function(){
    /**构建传送带对象，构建完成后，需要自行设定 .conveyer-head .conveyer-tail .conveyer-item$ 类名样式，以此来实现轮播图之类的效果
     * @param {String|Node} outer_selector 容器对象或者筛选标识
     * @param {Object} config 配置参数
     * @param {Number} config.index 初始序列号，默认为0
     * @param {Number} config.num 传送带上项目数量
     * @returns 
     */
    function Conveyer(outer_selector, config){
        if (!(this instanceof Conveyer)) return new Conveyer(outer_selector, config);
        if (outer_selector instanceof Node){
            if (outer_selector.nodeType!=1) throw new Error('Conveyer: 容器不存在');
            this.outer = outer_selector;
        }else {
            if (typeof(outer_selector)!='string') throw new Error('Conveyer: 容器不存在');
            this.outer = document.querySelector(outer_selector);
        }
        if (!this.outer) throw new Error('Conveyer: 容器不存在');
        this.config = typeof(config)=='object' ? config : {};
        //初始化
        if (!Conveyer.HIDDEN_CLASS){
            Conveyer.HIDDEN_CLASS = 'conveyer-hidden'+(new Date()).getTime();
            let style = document.createElement('style');
            style.innerHTML = '.'+Conveyer.HIDDEN_CLASS+'{display: none !important;}';
            document.querySelector('head').appendChild(style);
        }
        this.init(this.config.index || 0);
        return this;
    }
    function remainder(num, base){
        return num<0 ? base - (num*-1) % base : num%base;
    }

    Object.defineProperties(Conveyer.prototype, {
        init: {
            value: function (index){
                let items = this.outer.children;
                this.items_count = this.count = items.length;
                this.num = this.config.num || 1;
                if (this.num > this.count) {
                    throw new Error('容器内项目数量小于显示数量');
                }
                //如果容器中的项目数量小于N+3，需要拷贝所有项目到容器中
                while (this.items_count < this.num+3){
                    for (let i = 0; i < this.count; i++,this.items_count++) {
                        this.outer.appendChild(items[i].cloneNode(true));
                    }
                }
                this.items = this.outer.children;
                this._index = undefined;
                this.index = index || 0;
            }
        },
        index: {
            set: function (v){
                v = remainder(v, this.items_count);
                var dtV = 1;
                if (typeof(this._index)!='undefined'){
                    dtV = v >= this._index ? v - this._index : v + this.items_count - this._index;
                }
                if (!dtV) return;
                if (dtV > this.items_count/2) dtV = dtV - this.items_count;
                function change_class(dom, name){
                    let className = v.className || '';
                    dom.className = className.replace(/(^|\s)conveyer-(head|tail|hidden\d+|item\d+)/,"$1") + name;
                }
                var head_index = remainder(v-1, this.items_count),
                    tail_index = remainder(v+this.num, this.items_count),
                    item_index_arr = [], p;
                for (let i = 0; i < this.num; i++) {
                    item_index_arr.push( remainder(v+i, this.items_count) );
                }

                for (let i = 0,item; i < this.items.length; i++) {
                    item = this.items[i];
                    if (i===head_index){
                        change_class(item, 'conveyer-head');
                    }else if (i===tail_index){
                        change_class(item, 'conveyer-tail');
                    }else if (~(p = item_index_arr.indexOf(i))){
                        change_class(item, 'conveyer-item'+p);
                    }else {
                        change_class(item, Conveyer.HIDDEN_CLASS);
                    }
                }
                this._index = v;
            },
            get: function (){
                return this._index;
            }
        },
        next: {
            value: function (){ this.index++; }
        },
        prev: {
            value: function (){ this.index--; }
        },
    });

    return Conveyer;
})
